home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / Dylan Related / Mindy / Mindy 1.2 - portable sources / libraries / dylan / array.dylan next >
Encoding:
Text File  |  1995-03-15  |  7.6 KB  |  257 lines  |  [TEXT/ttxt]

  1. module:   dylan
  2. language: infix-dylan
  3. author:   Nick Kramer (nkramer@cs.cmu.edu)
  4. rcs-header: $Header: array.dylan,v 1.6 94/12/14 11:11:30 nkramer Exp $
  5.  
  6. //======================================================================
  7. //
  8. // Copyright (c) 1994  Carnegie Mellon University
  9. // All rights reserved.
  10. // 
  11. // Use and copying of this software and preparation of derivative
  12. // works based on this software are permitted, including commercial
  13. // use, provided that the following conditions are observed:
  14. // 
  15. // 1. This copyright notice must be retained in full on any copies
  16. //    and on appropriate parts of any derivative works.
  17. // 2. Documentation (paper or online) accompanying any system that
  18. //    incorporates this software, or any part of it, must acknowledge
  19. //    the contribution of the Gwydion Project at Carnegie Mellon
  20. //    University.
  21. // 
  22. // This software is made available "as is".  Neither the authors nor
  23. // Carnegie Mellon University make any warranty about the software,
  24. // its performance, or its conformity to any specification.
  25. // 
  26. // Bug reports, questions, comments, and suggestions should be sent by
  27. // E-mail to the Internet address "gwydion-bugs@cs.cmu.edu".
  28. //
  29. //======================================================================
  30.  
  31. // This is an array implementation that depends upon vectors being
  32. // already implemented.
  33.  
  34. define constant no-default = list(#"no-default");
  35.  
  36. define class <multiD-array> (<array>)
  37.   slot dimensions-slot  :: <simple-object-vector>;  // Sequence of integers
  38.   slot contents-slot    :: <simple-object-vector>;
  39.   slot size-slot        :: <fixed-integer>;
  40. end class <multiD-array>;
  41.  
  42. // General array methods
  43.  
  44. define method make (c :: singleton (<array>), 
  45.             #key dimensions: dimensions :: <sequence> = no-default,
  46.             fill: fill = #f);
  47.   if (dimensions == no-default)
  48.     error("Need the dimensions or a size for an array");
  49.   elseif (size(dimensions) = 1)
  50.     make(<vector>, fill: fill, size: head(dimensions));
  51.   else
  52.     make(<multiD-array>, dimensions: dimensions, fill: fill);
  53.   end if;
  54. end method make;
  55.  
  56.  
  57. define method row-major-index (array :: <array>, #rest indices)
  58.  => index :: <fixed-integer>;
  59.   let dims = dimensions(array);
  60.   let sum = 0;
  61.   if (size(indices) ~= size(dims))
  62.     error("Number of indices not equal to rank. Got %=, wanted %d indices",
  63.       indices, size(dims));
  64.   else
  65.     for (index in indices,
  66.      dim   in dims)
  67.       if (index < 0 | index >= dim)
  68.     error("Array index out of bounds: %= in %=", index, indices);
  69.       else
  70.     sum := (sum * dim) + index;
  71.       end if;
  72.     end for;
  73.     sum;
  74.   end if;
  75. end method row-major-index;           
  76.  
  77.  
  78. define method aref (array :: <array>, #rest indices)
  79.  => elt :: <object>;
  80.   let index = apply(row-major-index, array, indices);
  81.   array[index];             // Call element
  82. end method aref;
  83.  
  84.  
  85. define method aref-setter (value :: <object>, array :: <array>, 
  86.                #rest indices) => value :: <object>;
  87.   let index = apply(row-major-index, array, indices);
  88.   array [index] := value;    // Call element-setter
  89. end method aref-setter;
  90.  
  91.  
  92. // rank -- the number of dimensions
  93. //
  94. define method rank (array :: <array>) => the-rank-of-array :: <fixed-integer>;
  95.   size(dimensions(array));
  96. end method rank;
  97.  
  98.  
  99. // Also defined below on multiD-arrays
  100. //
  101. define method size (array :: <array>) => size :: <fixed-integer>;
  102.   reduce(\*, 1, dimensions(array));
  103. end method size;
  104.  
  105.  
  106. define method dimension (array :: <array>, axis :: <fixed-integer>) 
  107.              => dim-of-that-axis :: <fixed-integer>;
  108.   element(dimensions(array), axis);
  109. end method dimension;
  110.  
  111.  
  112. define method forward-iteration-protocol (array :: <array>)
  113.   => (initial-state          :: <fixed-integer>,
  114.       limit                  :: <fixed-integer>,
  115.       next-state             :: <function>,  finished-state? :: <function>,
  116.       current-key            :: <function>,  current-element :: <function>,
  117.       current-element-setter :: <function>,  copy-state      :: <function>);
  118.   values(0,                 // initial state
  119.      size(array),       // limit 
  120.  
  121.           // next-state
  122.      method (array :: <array>, state :: <fixed-integer>) 
  123.       => next-state :: <fixed-integer>;
  124.        state + 1;
  125.      end method,
  126.  
  127.           // finished-state?
  128.      method (array :: <array>, state :: <fixed-integer>,
  129.          limit :: <fixed-integer>)
  130.       => answer :: <boolean>;
  131.        state = limit;
  132.      end method,
  133.  
  134.          // current-key
  135.      method (array :: <array>, state :: <fixed-integer>)
  136.          => key :: <fixed-integer>;
  137.        state;
  138.      end method,
  139.  
  140.          // current-element
  141.      method (array :: <array>, state :: <fixed-integer>)
  142.        array[state];
  143.      end method,
  144.  
  145.         // current-element-setter
  146.      method (value, array :: <array>, state :: <fixed-integer>)
  147.        array [state] := value;
  148.      end method,
  149.  
  150.         // copy-state
  151.      method (array :: <array>, state :: <fixed-integer>) 
  152.       => new-state :: <fixed-integer>;
  153.        state;
  154.      end method);
  155. end method forward-iteration-protocol;
  156.  
  157.  
  158. define method backward-iteration-protocol (array :: <array>)
  159.   => (final-state            :: <fixed-integer>,
  160.       limit                  :: <fixed-integer>,
  161.       previous-state         :: <function>,  finished-state? :: <function>,
  162.       current-key            :: <function>,  current-element :: <function>,
  163.       current-element-setter :: <function>,  copy-state      :: <function>);
  164.  
  165.   values(size (array) - 1,                 // final state
  166.      -1,                               // limit 
  167.  
  168.          // next-state
  169.      method (array :: <array>, state :: <fixed-integer>)    
  170.        state - 1;
  171.      end method,
  172.  
  173.          // Everything else the same as forward-iteration-protocol
  174.  
  175.          // finished-state?
  176.      method (array :: <array>, state :: <fixed-integer>,
  177.          limit :: <fixed-integer>)
  178.        state = limit;
  179.      end method,
  180.  
  181.          // current-key
  182.      method (array :: <array>, state :: <fixed-integer>)
  183.          => key :: <fixed-integer>;
  184.        state;
  185.      end method,
  186.  
  187.          // current-element
  188.      method (array :: <array>, state :: <fixed-integer>)
  189.        array [state];
  190.      end method,
  191.  
  192.         // current-element-setter
  193.      method (value, array :: <array>, state :: <fixed-integer>)
  194.        array [state] := value;
  195.      end method,
  196.  
  197.         // copy-state
  198.      method (array :: <array>, state :: <fixed-integer>) 
  199.       => new-state :: <fixed-integer>;
  200.        state;
  201.      end method);
  202. end method backward-iteration-protocol;
  203.  
  204.  
  205. // multiD-array code
  206.  
  207.  
  208. define method initialize (array :: <multiD-array>, 
  209.               #key dimensions: dimensions :: <sequence>,
  210.               fill: fill = #f);
  211.  
  212.   if (size(dimensions) == 1 )
  213.     // This code should never be executed unless someone calls
  214.     // make on a <multiD-array> instead of make (<array>)
  215.  
  216.     error("Can't make a <multiD-array> with 1 dimension");
  217.   end if;
  218.   array.dimensions-slot := as(<simple-object-vector>, dimensions);
  219.   let total-size = reduce(\*, 1, array.dimensions-slot);
  220.   array.size-slot := total-size;
  221.   array.contents-slot := make(<simple-object-vector>, 
  222.                   size: total-size, fill: fill);
  223. end method initialize;
  224.  
  225.  
  226. define method element (array :: <multiD-array>, index :: <fixed-integer>,
  227.                #key default: default = no-default);
  228.   if (default == no-default)
  229.     array.contents-slot[index];
  230.   else
  231.     element(array.contents-slot, index, default: default);
  232.   end if;
  233. end method element;
  234.  
  235.  
  236. define method element-setter (value, array :: <multiD-array>, 
  237.                   index :: <fixed-integer>);
  238.   array.contents-slot[index] := value;
  239. end method element-setter;
  240.  
  241.  
  242. define method size (array :: <multiD-array>) => size :: <fixed-integer>;
  243.   array.size-slot;
  244. end method size;
  245.  
  246.  
  247. define method shallow-copy (array :: <multiD-array>)
  248.  => new-array :: <multiD-array>;
  249.   let new-array = make(<multiD-array>, dimensions: array.dimensions);
  250.   map-into(new-array, identity, array);
  251. end method shallow-copy;
  252.  
  253.  
  254. define method dimensions (array :: <multiD-array>) => dimensions :: <sequence>;
  255.   array.dimensions-slot;
  256. end method dimensions;
  257.